﻿

using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Linq;
using System.Net;
using System.Web;
using System.Web.Mvc;
using Repository.Pattern.UnitOfWork;
using Repository.Pattern.Infrastructure;
using WebApp.Models;
using WebApp.Services;
using WebApp.Repositories;
using WebApp.Extensions;


namespace WebApp.Controllers
{
     public class MenuItemsController : Controller
    {

        //Please RegisterType UnityConfig.cs
        //container.RegisterType<IRepositoryAsync<MenuItem>, Repository<MenuItem>>();
        //container.RegisterType<IMenuItemService, MenuItemService>();

        //private TmsAppContext db = new TmsAppContext();
        private readonly IMenuItemService _menuItemService;
        private readonly IUnitOfWorkAsync _unitOfWork;


        public MenuItemsController(IMenuItemService menuItemService, IUnitOfWorkAsync unitOfWork)
        {
            _menuItemService = menuItemService;
            _unitOfWork = unitOfWork;
        }

        // GET: MenuItems/Index
        public ActionResult Index()
        {

            var menuitems = _menuItemService.Queryable().Include(m => m.Parent).AsQueryable();

            return View(menuitems);
        }

        // Get :MenuItems/PageList
        // For Index View Boostrap-Table load  data 
        [HttpGet]
        public ActionResult PageList(int offset = 0, int limit = 10, string search = "", string sort = "", string order = "")
        {
            int totalCount = 0;
            int pagenum = offset / limit + 1;
            var menuitems = _menuItemService.Query(new MenuItemQuery().WithAnySearch(search)).Include(m => m.Parent).OrderBy(n => n.OrderBy(sort, order)).SelectPage(pagenum, limit, out totalCount);

            var rows = menuitems.Select(n => new { ParentTitle = (n.Parent == null ? "" : n.Parent.Title), Id = n.Id, Title = n.Title, Description = n.Description, Code = n.Code, Url = n.Url, IsEnabled = n.IsEnabled, ParentId = n.ParentId }).ToList();
            var pagelist = new { total = totalCount, rows = rows };
            return Json(pagelist, JsonRequestBehavior.AllowGet);
        }


        // GET: MenuItems/Details/5
        public ActionResult Details(int? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }
            MenuItem menuItem = _menuItemService.Find(id);
            if (menuItem == null)
            {
                return HttpNotFound();
            }
            return View(menuItem);
        }


        // GET: MenuItems/Create
        public ActionResult Create()
        {
            MenuItem menuItem = new MenuItem();
            menuItem.IsEnabled = true;
            //set default value
            var menuitemRepository = _unitOfWork.Repository<MenuItem>();
            ViewBag.ParentId = new SelectList(menuitemRepository.Queryable(), "Id", "Title");
            return View(menuItem);
        }

        // POST: MenuItems/Create
        // To protect from overposting attacks, please enable the specific properties you want to bind to, for more details see http://go.microsoft.com/fwlink/?LinkId=317598.
        [HttpPost]
        //[ValidateAntiForgeryToken]
        public ActionResult Create([Bind(Include = "Parent,SubMenus,Id,Title,Description,Code,Url,IsEnabled,ParentId")] MenuItem menuItem)
        {
            if (ModelState.IsValid)
            {
                menuItem.ObjectState = ObjectState.Added;
                foreach (var item in menuItem.SubMenus)
                {
                    item.ParentId = menuItem.Id;
                    item.ObjectState = ObjectState.Added;
                }
                _menuItemService.InsertOrUpdateGraph(menuItem);
                _unitOfWork.SaveChanges();
                if (Request.IsAjaxRequest())
                {
                    return Json(new { success = true }, JsonRequestBehavior.AllowGet);
                }
                DisplaySuccessMessage("Has append a MenuItem record");
                return RedirectToAction("Index");
            }

            var menuitemRepository = _unitOfWork.Repository<MenuItem>();
            ViewBag.ParentId = new SelectList(menuitemRepository.Queryable(), "Id", "Title", menuItem.ParentId);
            if (Request.IsAjaxRequest())
            {
                var modelStateErrors = String.Join("", this.ModelState.Keys.SelectMany(key => this.ModelState[key].Errors.Select(n => n.ErrorMessage)));
                return Json(new { success = false, err = modelStateErrors }, JsonRequestBehavior.AllowGet);
            }
            DisplayErrorMessage();
            return View(menuItem);
        }

        // GET: MenuItems/Edit/5
        public ActionResult Edit(int? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }
            MenuItem menuItem = _menuItemService.Find(id);
            if (menuItem == null)
            {
                return HttpNotFound();
            }
            var menuitemRepository = _unitOfWork.Repository<MenuItem>();
            ViewBag.ParentId = new SelectList(menuitemRepository.Queryable(), "Id", "Title", menuItem.ParentId);
            return View(menuItem);
        }

        // POST: MenuItems/Edit/5
        // To protect from overposting attacks, please enable the specific properties you want to bind to, for more details see http://go.microsoft.com/fwlink/?LinkId=317598.
        [HttpPost]
        //[ValidateAntiForgeryToken]
        public ActionResult Edit([Bind(Include = "Parent,SubMenus,Id,Title,Description,Code,Url,IsEnabled,ParentId")] MenuItem menuItem)
        {
            if (ModelState.IsValid)
            {
                menuItem.ObjectState = ObjectState.Modified;
                foreach (var item in menuItem.SubMenus)
                {
                    item.ParentId = menuItem.Id;
                    //set ObjectState with conditions
                    if (item.Id <= 0)
                        item.ObjectState = ObjectState.Added;
                    else
                        item.ObjectState = ObjectState.Modified;
                }

                _menuItemService.InsertOrUpdateGraph(menuItem);

                _unitOfWork.SaveChanges();
                if (Request.IsAjaxRequest())
                {
                    return Json(new { success = true }, JsonRequestBehavior.AllowGet);
                }
                DisplaySuccessMessage("Has update a MenuItem record");
                return RedirectToAction("Index");
            }
            var menuitemRepository = _unitOfWork.Repository<MenuItem>();
            ViewBag.ParentId = new SelectList(menuitemRepository.Queryable(), "Id", "Title", menuItem.ParentId);
            if (Request.IsAjaxRequest())
            {
                var modelStateErrors = String.Join("", this.ModelState.Keys.SelectMany(key => this.ModelState[key].Errors.Select(n => n.ErrorMessage)));
                return Json(new { success = false, err = modelStateErrors }, JsonRequestBehavior.AllowGet);
            }
            DisplayErrorMessage();
            return View(menuItem);
        }

        // GET: MenuItems/Delete/5
        public ActionResult Delete(int? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }
            MenuItem menuItem = _menuItemService.Find(id);
            if (menuItem == null)
            {
                return HttpNotFound();
            }
            return View(menuItem);
        }

        // POST: MenuItems/Delete/5
        [HttpPost, ActionName("Delete")]
        //[ValidateAntiForgeryToken]
        public ActionResult DeleteConfirmed(int id)
        {
            MenuItem menuItem = _menuItemService.Find(id);
            _menuItemService.Delete(menuItem);
            _unitOfWork.SaveChanges();
            if (Request.IsAjaxRequest())
            {
                return Json(new { success = true }, JsonRequestBehavior.AllowGet);
            }
            DisplaySuccessMessage("Has delete a MenuItem record");
            return RedirectToAction("Index");
        }


        // Get Detail Row By Id For Edit
        // Get : MenuItems/EditMenuItem/:id
        [HttpGet]
        public ActionResult EditMenuItem(int? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }
            var menuitemRepository = _unitOfWork.Repository<MenuItem>();
            var menuitem = menuitemRepository.Find(id);



            if (menuitem == null)
            {
                ViewBag.ParentId = new SelectList(menuitemRepository.Queryable(), "Id", "Title");

                //return HttpNotFound();
                return PartialView("_MenuItemEditForm", new MenuItem() { IsEnabled = true });
            }
            else
            {
                ViewBag.ParentId = new SelectList(menuitemRepository.Queryable(), "Id", "Title", menuitem.ParentId);

            }
            return PartialView("_MenuItemEditForm", menuitem);

        }

        // Get Create Row By Id For Edit
        // Get : MenuItems/CreateMenuItem
        [HttpGet]
        public ActionResult CreateMenuItem()
        {
            var menuitemRepository = _unitOfWork.Repository<MenuItem>();
            ViewBag.ParentId = new SelectList(menuitemRepository.Queryable(), "Id", "Title");
            return PartialView("_MenuItemEditForm");

        }

        // Post Delete Detail Row By Id
        // Get : MenuItems/DeleteMenuItem/:id
        [HttpPost, ActionName("DeleteMenuItem")]
        public ActionResult DeleteMenuItemConfirmed(int id)
        {
            var menuitemRepository = _unitOfWork.Repository<MenuItem>();
            menuitemRepository.Delete(id);
            _unitOfWork.SaveChanges();
            if (Request.IsAjaxRequest())
            {
                return Json(new { success = true }, JsonRequestBehavior.AllowGet);
            }
            DisplaySuccessMessage("Has delete a Order record");
            return RedirectToAction("Index");
        }



        // Get : MenuItems/GetSubMenusByParentId/:id
        [HttpGet]
        public ActionResult GetSubMenusByParentId(int id)
        {
            var submenus = _menuItemService.GetSubMenusByParentId(id);
            if (Request.IsAjaxRequest())
            {
                return Json(submenus.Select(n => new { ParentTitle = (n.Parent == null ? "" : n.Parent.Title), Id = n.Id, Title = n.Title, Description = n.Description, Code = n.Code, Url = n.Url, IsEnabled = n.IsEnabled, ParentId = n.ParentId }), JsonRequestBehavior.AllowGet);
            }
            return View(submenus);

        }


        private void DisplaySuccessMessage(string msgText)
        {
            TempData["SuccessMessage"] = msgText;
        }

        private void DisplayErrorMessage()
        {
            TempData["ErrorMessage"] = "Save changes was unsuccessful.";
        }

        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                _unitOfWork.Dispose();
            }
            base.Dispose(disposing);
        }
    }
}
